package com.guoqi.marrydate.fm

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.support.v4.app.Fragment
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.alibaba.fastjson.JSON
import com.guoqi.marrydate.calendar.OnCalendarClickListener
import com.guoqi.marrydate.calendar.schedule.ScheduleAdapter
import com.guoqi.marrydate.flag.FlagBean
import com.lxj.xpopup.XPopup
import kotlinx.android.synthetic.main.fm_calendar.*
import org.litepal.LitePal
import org.litepal.crud.callback.FindMultiCallback
import java.io.File
import java.io.IOException
import java.io.RandomAccessFile
import java.nio.charset.Charset
import java.util.*


class CalendarFm : Fragment() {

    companion object {

        var instance: CalendarFm? = null
        //val filePath = Environment.getExternalStorageDirectory().absolutePath + "/download/flag.json"
        //默认保存到微信文件夹
        val filePath = Environment.getExternalStorageDirectory().absolutePath + File.separator + "tencent/MicroMsg/Download/flag.json"

        fun newInstance(args: String): CalendarFm {
            val fragment = CalendarFm()
            val bundle = Bundle()
            bundle.putString("fragment", args)
            fragment.arguments = bundle
            return fragment
        }
    }

    private var mCurrentSelectYear: Int = 0
    private var mCurrentSelectMonth: Int = 0
    private var mCurrentSelectDay: Int = 0
    private lateinit var mMonthText: Array<String>

    private lateinit var scheduleAdapter: ScheduleAdapter
    private lateinit var eventList: ArrayList<FlagBean>

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(com.guoqi.marrydate.R.layout.fm_calendar, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        activity?.let {
            instance = this
            initUI()
            initData()
        }
    }

    private fun initUI() {
        initScheduleList()
        slSchedule.setOnCalendarClickListener(object : OnCalendarClickListener {
            override fun onClickDate(year: Int, month: Int, day: Int) {
                setCurrentSelectDate(year, month, day)
            }

            override fun onPageChange(year: Int, month: Int, day: Int) {
            }
        })
        tv_toToday.setOnClickListener {
            mcvCalendar.setTodayToView()
        }
        tv_more.setOnClickListener {
            XPopup.Builder(context)
                    .asBottomList("请选择需要执行的操作", arrayOf("导入", "导出", "清空", "关于作者(gooqii)")
                    ) { _, text ->
                        when (text) {
                            "导入" -> {
                                showImportDialog()
                            }
                            "导出" -> {
                                showExportDialog()
                            }
                            "清空" -> {
                                showClearDialog()
                            }
                            "关于作者(gooqii)" -> {
                                val uri = Uri.parse("https://madaigou.oschina.io/gqblog/about/")
                                val intent = Intent(Intent.ACTION_VIEW, uri)
                                startActivity(intent)
                            }
                        }
                    }
                    .show()
        }

    }


    private fun initScheduleList() {
        val manager = LinearLayoutManager(activity)
        manager.orientation = LinearLayoutManager.VERTICAL
        rvScheduleList.layoutManager = manager
        val itemAnimator = DefaultItemAnimator()
        itemAnimator.supportsChangeAnimations = false
        rvScheduleList.itemAnimator = itemAnimator
        scheduleAdapter = ScheduleAdapter(activity!!)
        rvScheduleList.adapter = scheduleAdapter
    }

    open fun initData() {
        mMonthText = resources.getStringArray(com.guoqi.marrydate.R.array.calendar_month)

        val calendar = Calendar.getInstance()
        mCurrentSelectYear = calendar.get(Calendar.YEAR)
        mCurrentSelectMonth = calendar.get(Calendar.MONTH)
        mCurrentSelectDay = calendar.get(Calendar.DAY_OF_MONTH)
        resetDateText(mCurrentSelectYear, mCurrentSelectMonth, mCurrentSelectDay)
    }


    private fun setCurrentSelectDate(year: Int, month: Int, day: Int) {
        mCurrentSelectYear = year
        mCurrentSelectMonth = month
        mCurrentSelectDay = day
        resetDateText(year, month, day)
    }

    private fun resetSchedule(year: Int, month: Int, day: Int) {
        var monthStr = (month + 1).toString()
        if (month + 1 < 10) {
            monthStr = "0$monthStr"
        }
        var dayStr = day.toString()
        if (day < 10) {
            dayStr = "0$day"
        }
        var date = "$year-$monthStr-$dayStr"
        LitePal.where("date=?", date).order("sortNo desc").findAsync(FlagBean::class.java).listen(object : FindMultiCallback {
            override fun <T> onFinish(t: List<T>) {
                eventList = t as ArrayList<FlagBean>
                if (eventList.isNotEmpty()) {
                    rlNoTask.visibility = View.GONE
                    rvScheduleList.visibility = View.VISIBLE
                    scheduleAdapter.resetData(eventList)
                } else {
                    rvScheduleList.visibility = View.GONE
                    rlNoTask.visibility = View.VISIBLE
                }
            }
        })
    }

    private fun resetDateText(year: Int, month: Int, day: Int) {
        val calendar = Calendar.getInstance()
        if (year == calendar.get(Calendar.YEAR) && month == calendar.get(Calendar.MONTH) && day == calendar.get(Calendar.DAY_OF_MONTH)) {
            //今日
            tv_more.visibility = View.VISIBLE
            tv_toToday.visibility = View.GONE
            tv_select.text = """${year}年${mMonthText[month]}${day}日 (${getString(com.guoqi.marrydate.R.string.calendar_today)})"""
        } else {
            tv_more.visibility = View.GONE
            tv_toToday.visibility = View.VISIBLE
            tv_select.text = """${year}年${mMonthText[month]}${day}日"""
        }
        resetSchedule(year, month, day)
    }

    private fun showImportDialog() {
        XPopup.Builder(activity)
                .asConfirm("导入", "把json文件发送至微信, 将会自动识别导入？\n\n此操作将不会覆盖现有的flag列表！") {
                    importFile()
                }.show()
    }


    private fun showExportDialog() {
        XPopup.Builder(activity)
                .asConfirm("导出", "确定要导出所有flag到 /tencent/MicroMsg/Download/flag.json文件？\n\n此操作将会覆盖之前导出的文件！") {
                    exportFile()
                }.show()
    }

    private fun showClearDialog() {
        XPopup.Builder(activity)
                .asConfirm("提示", "确定要清空所有flag吗？") {
                    LitePal.deleteAll(FlagBean::class.java, " 1=1")
                    Toast.makeText(activity, "flag已清空", Toast.LENGTH_SHORT).show()
                    initData()
                    FlagFm.instance?.initData()
                }.show()
    }

    private fun importFile() {
        if (File(filePath).exists()) {
            var result = File(filePath).readText(Charset.forName("UTF-8"))
            //Log.e("CalendarFm", "导入结果:$result")
            var importList = JSON.parseArray(result, FlagBean::class.java) as ArrayList<FlagBean>
            if (importList.isNotEmpty()) {
                showImportOverrideDialog(importList)
            } else {
                Toast.makeText(activity, "导入失败: 数据为空！", Toast.LENGTH_SHORT).show()
            }
        } else {
            Toast.makeText(activity, "导入失败: 文件不存在！", Toast.LENGTH_SHORT).show()
        }
    }

    private fun exportFile() {
        createFileByDeleteOldFile(File(filePath))
        LitePal.where("1=1").order("sortNo desc,date asc").findAsync(FlagBean::class.java).listen(object : FindMultiCallback {
            override fun <T> onFinish(t: List<T>) {
                eventList = t as ArrayList<FlagBean>
                if (eventList.isNotEmpty()) {
                    //执行导出
                    val strContent = JSON.toJSONString(eventList)
                    try {
                        val file = File(filePath)
                        val raf = RandomAccessFile(file, "rwd")
                        raf.seek(file.length())
                        raf.write(strContent.toByteArray())
                        raf.close()
                        Toast.makeText(activity, "导出成功！共${eventList.size}条flag", Toast.LENGTH_SHORT).show()
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Toast.makeText(activity, "导出失败: ${e.message}", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    Toast.makeText(activity, "暂无数据, 无法导出！", Toast.LENGTH_SHORT).show()
                }
            }
        })
    }

    private fun showImportOverrideDialog(list: ArrayList<FlagBean>) {
        XPopup.Builder(activity)
                .asConfirm("提示", "确定要导入${list.size}条数据吗？") {
                    LitePal.saveAllAsync(list).listen {
                        if (it) {
                            initData()
                            FlagFm.instance?.initData()
                            Toast.makeText(activity, "导入成功！", Toast.LENGTH_SHORT).show()
                        }
                    }
                }
                .show()
    }


    private fun createFileByDeleteOldFile(file: File?): Boolean {
        if (file == null) return false
        if (file.exists() && !file.delete()) return false
        if (!createOrExistsDir(file.parentFile)) return false
        return try {
            file.createNewFile()
        } catch (e: IOException) {
            e.printStackTrace()
            false
        }
    }

    private fun createOrExistsDir(file: File?): Boolean {
        return file != null && if (file.exists()) file.isDirectory else file.mkdirs()
    }

}